package org.jiuling.aliyun.oss.operation;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.*;
import org.jiuling.aliyun.oss.client.enums.EndpointEnum;
import org.jiuling.aliyun.oss.client.factory.AliYunOssClientFactory;
import org.jiuling.aliyun.oss.dto.CreateBucketParam;
import org.jiuling.aliyun.oss.exception.AliYunOssRuntimeException;
import org.jiuling.basics.exception.BasicsException;
import org.jiuling.basics.util.EnumUtil;
import org.jiuling.basics.validation.Assertions;
import org.jiuling.basics.validation.ObjectVerify;
import org.jiuling.basics.validation.StringVerify;

import java.util.List;

/**
 * 存储空间操作
 * @author 紫灵
 * @date 2024年06月15日 21时13分49秒
 */
public class AliYunBucketOperation {

    /** 阿里云对象存储客户端工厂 */
    private final AliYunOssClientFactory aliYunOssClientFactory;

    public AliYunBucketOperation(AliYunOssClientFactory aliYunOssClientFactory) {
        this.aliYunOssClientFactory = aliYunOssClientFactory;
    }

    /**
     * 创建储存空间
     * @param bucketName 空间名称
     * @param createBucketParam 创建存储空间参数
     */
    public Bucket createBucket(String bucketName, CreateBucketParam createBucketParam){
        // 创建OSSClient实例。
        OSS ossClient = aliYunOssClientFactory.buildOssClient();
        // 创建CreateBucketRequest对象。
        CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
        if (!ObjectVerify.isNull(createBucketParam)) {

            StorageClass storageClass = createBucketParam.getStorageClass();
            if(!ObjectVerify.isNull(storageClass)) {
                // 此处以设置存储空间的存储类型为标准存储为例介绍。
                createBucketRequest.setStorageClass(storageClass);
            }

            CannedAccessControlList cannedAccessControlList = createBucketParam.getCannedAccessControlList();
            if (!ObjectVerify.isNull(cannedAccessControlList)){
                // 设置存储空间读写权限为公共读，默认为私有。
                createBucketRequest.setCannedACL(cannedAccessControlList);
            }

            DataRedundancyType dataRedundancyType = createBucketParam.getDataRedundancyType();
            if (!ObjectVerify.isNull(dataRedundancyType)){
                // 数据容灾类型默认为本地冗余存储，即DataRedundancyType.LRS。如果需要设置数据容灾类型为同城冗余存储，请设置为DataRedundancyType.ZRS。
                createBucketRequest.setDataRedundancyType(dataRedundancyType);
            }

            String resourceGroupId = createBucketParam.getResourceGroupId();
            if (!StringVerify.isNull(resourceGroupId)){
                // 在支持资源组的地域创建Bucket时，您可以为Bucket配置资源组。
                createBucketRequest.setResourceGroupId(resourceGroupId);
            }

        }

        try {
            // 创建存储空间。
            return ossClient.createBucket(createBucketRequest);
        }finally {
            aliYunOssClientFactory.closeClient(ossClient);
        }

    }

    /**
     * 获取存储空间列表
     * @return 存储空间列表
     */
    public List<Bucket> getListBuckets() {
        // 创建OSSClient实例。
        OSS ossClient = aliYunOssClientFactory.buildOssClient();
        try {
            // 列举当前账号所有地域下的存储空间。
            return ossClient.listBuckets();
        }finally {
            aliYunOssClientFactory.closeClient(ossClient);
        }
    }

    /**
     * 判断存储空间是否存在
     * @param bucketName 空间名称
     * @return 是否存在
     */
    public boolean existBucket(String bucketName){
        // 创建OSSClient实例。
        OSS ossClient = aliYunOssClientFactory.buildOssClient();
        try{
            return ossClient.doesBucketExist(bucketName);
        }finally {
            aliYunOssClientFactory.closeClient(ossClient);
        }
    }

    /**
     * 获取存储空间地域
     * @param bucketName 存储空间名称
     * @return 存储空间地域
     */
    public String getBucketLocation(String bucketName){
        // 创建OSSClient实例。
        OSS ossClient = aliYunOssClientFactory.buildOssClient();
        try {
            // 列举当前账号所有地域下的存储空间。
            return ossClient.getBucketLocation(bucketName);
        }finally {
            aliYunOssClientFactory.closeClient(ossClient);
        }
    }

    /**
     * 获取储存空间地域枚举
     * @param bucketName 存储空空间名称
     * @return 存储空间地域枚举
     */
    public EndpointEnum getBucketEndpoint(String bucketName){
        try {
            return EnumUtil.valueOfEnum(EndpointEnum.class,getBucketLocation(bucketName),"ossRegionId");
        } catch (BasicsException e) {
            throw new AliYunOssRuntimeException(e);
        }
    }

    /**
     * 获取存储空间
     * @param bucketName 存储空间名称
     * @return 存储空间
     */
    public Bucket getBucket(String bucketName){
        return this.getBucketInfo(bucketName).getBucket();
    }

    /**
     * 获取存储空间信息
     * @param bucketName 存储空间名称
     * @return 存储空间信息
     */
    public BucketInfo getBucketInfo(String bucketName){
        // 创建OSSClient实例。
        OSS ossClient = aliYunOssClientFactory.buildOssClient();
        try {
            return ossClient.getBucketInfo(bucketName);
        }finally {
            aliYunOssClientFactory.closeClient(ossClient);
        }
    }

    /**
     * 获取存储空间的存储容量
     * @param bucketName 存储空间名称
     * @return 存储容量
     */
    public BucketStat getBucketStat(String bucketName){
        // 创建OSSClient实例。
        OSS ossClient = aliYunOssClientFactory.buildOssClient();
        try {
            return ossClient.getBucketStat(bucketName);
        }finally {
            aliYunOssClientFactory.closeClient(ossClient);
        }
    }

    /**
     * 删除存储空间
     * @param bucketName 存储空间名称
     */
    public void deleteBucket(String bucketName){
        Assertions.StringAssertions.isNotBlank("存储空间名称不能为空！",bucketName);
        Assertions.isTrue("该存储空间不存在！",this.existBucket(bucketName));
        // 创建OSSClient实例。
        OSS ossClient = aliYunOssClientFactory.buildOssClient();
        try {
            ossClient.deleteBucket(bucketName);
        }finally {
            aliYunOssClientFactory.closeClient(ossClient);
        }

    }

}
